// 异常处理示例 - 演示Java异常处理机制
import java.io.*;

// 自定义异常类
class InvalidAgeException extends Exception {
    public InvalidAgeException(String message) {
        super(message);
    }
}

// 学生管理类 - 演示异常处理
class StudentManager {
    private String name;
    private int age;
    
    public StudentManager(String name, int age) throws InvalidAgeException {
        if (age < 0 || age > 150) {
            // 抛出自定义异常
            throw new InvalidAgeException("年龄必须在0-150之间");
        }
        this.name = name;
        this.age = age;
    }
    
    // 演示throws关键字 - 声明可能抛出的异常
    public void readFile(String fileName) throws IOException {
        // 可能抛出FileNotFoundException或IOException
        FileReader file = new FileReader(fileName);
        BufferedReader reader = new BufferedReader(file);
        System.out.println(reader.readLine());
        reader.close();
    }
    
    // 演示try-catch-finally语句块
    public double divideGrades(int totalScore, int subjectCount) {
        double average = 0.0;
        try {
            // 可能抛出ArithmeticException异常
            average = totalScore / subjectCount;
            System.out.println("计算成功，平均分: " + average);
        } catch (ArithmeticException e) {
            // 捕获除零异常
            System.out.println("错误：科目数量不能为0");
            // 异常链 - 重新抛出异常并保留原始异常信息
            throw new RuntimeException("计算平均分失败", e);
        } finally {
            // finally块总是执行，用于清理资源
            System.out.println("计算完成");
        }
        return average;
    }
    
    // 演示try-with-resources语句（Java 7+）
    public void readStudentData(String fileName) {
        // try-with-resources自动关闭资源，无需手动调用close()
        try (FileReader file = new FileReader(fileName);
             BufferedReader reader = new BufferedReader(file)) {
            
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (FileNotFoundException e) {
            System.out.println("文件未找到: " + fileName);
        } catch (IOException e) {
            System.out.println("读取文件时发生错误: " + e.getMessage());
        }
        // 资源会自动关闭，无需在finally块中处理
    }
    
    public String getName() {
        return name;
    }
    
    public int getAge() {
        return age;
    }
}

// 异常处理演示主类
public class ExceptionHandlingExample {
    public static void main(String[] args) {
        // 演示自定义异常处理
        try {
            StudentManager student = new StudentManager("张三", -5);
        } catch (InvalidAgeException e) {
            System.out.println("创建学生对象失败: " + e.getMessage());
        }
        
        StudentManager student2 = null;
        try {
            student2 = new StudentManager("李四", 20);
        } catch (InvalidAgeException e) {
            System.out.println("创建学生对象失败: " + e.getMessage());
        }
        
        if (student2 != null) {
            // 演示算术异常处理
            try {
                student2.divideGrades(400, 0);
            } catch (RuntimeException e) {
                System.out.println("捕获到运行时异常: " + e.getMessage());
                // 打印异常链
                System.out.println("原始异常: " + e.getCause());
            }
            
            // 演示try-with-resources
            student2.readStudentData("students.txt");
            
            // 演示文件未找到异常
            try {
                student2.readFile("nonexistent.txt");
            } catch (IOException e) {
                System.out.println("文件操作异常: " + e.getMessage());
            }
        }
        
        // 演示Throwable类体系结构
        demonstrateExceptionHierarchy();
    }
    
    // 演示异常类体系结构
    public static void demonstrateExceptionHierarchy() {
        System.out.println("\n=== 异常类体系结构演示 ===");
        
        try {
            // 演示不同类型的异常
            int[] arr = new int[5];
            arr[10] = 5; // ArrayIndexOutOfBoundsException - RuntimeException的子类
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("捕获数组越界异常: " + e.getClass().getSimpleName());
        }
        
        try {
            String str = null;
            int len = str.length(); // NullPointerException - RuntimeException的子类
        } catch (NullPointerException e) {
            System.out.println("捕获空指针异常: " + e.getClass().getSimpleName());
        }
        
        // 显示Throwable的两个主要子类
        System.out.println("Throwable主要子类:");
        System.out.println("- Error (错误，通常不需要程序处理)");
        System.out.println("- Exception (异常，程序需要处理)");
        System.out.println("  - RuntimeException (运行时异常，非检查异常)");
        System.out.println("  - 其他Exception子类 (检查异常，必须处理)");
    }
}